#include "../include/WebPageOffline.hpp"
#include <sstream> 
#include <queue>

using std::stringstream;
using std::priority_queue;
namespace wd
{

WebPageOffline::WebPageOffline(const string &doc, SplitTool &SplitTool, set<string>& stopWords)
: _doc(doc)
, _totalWords(0)
, _splitTool(SplitTool)
, _stopWords(stopWords)
{
    processDoc();
}

string WebPageOffline::getDoc() const
{
    return _doc;
}

int WebPageOffline::getTotalWords() const
{
    return _totalWords;
}

map<string, int>& WebPageOffline::getWordsMap()
{
    return _wordsMap;
}

bool operator==(const WebPageOffline &lhs, const WebPageOffline &rhs)
{
	vector<string> vec1 = lhs._topWords;
	vector<string> vec2 = rhs._topWords;
	vector<string> intersection;
	std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), back_inserter(intersection));
	if (intersection.size() == TOPK_NUMBER) //前K个高频词都相同
		return true;
	else
		return false;
}

struct Comp
{
	bool operator()(const pair<string, int> &lhs, const pair<string, int> &rhs)
	{
		return lhs.second > rhs.second; //降序，形成小顶堆
	}
};

void WebPageOffline::processDoc()
{
	stringstream ss(_doc);
	string word;
	while (ss >> word)
	{
		if ("<title>" == word)
		{
			ss >> _title;
			//统计词频
			storeWordsMap(_title);
		}
		else if ("<link>" == word)
		{
			ss >> _link;
		}
		else if ("<description>" == word)
		{
			ss >> _description;
			//统计词频
			storeWordsMap(_description);
		}
		else if ("<content>" == word)
		{
			ss >> _content;
			//统计词频
			storeWordsMap(_content);
		}
	}

	//获取单词总数
	for (auto &e : _wordsMap)
	{
		_totalWords += e.second;
	}

	//计算出前K频率的词
	calcTopK(TOPK_NUMBER);
} 

void WebPageOffline::storeWordsMap(const string &s)
{
	vector<string> vec = _splitTool.cut(s);
	for (auto &e : vec)
	{
		if (_stopWords.find(e) != _stopWords.end())
			continue;
		_wordsMap[e]++;
	}
}

void WebPageOffline::calcTopK(size_t k)
{
	priority_queue<pair<string, int>, vector<pair<string, int>>, Comp> priQue;
	for (auto &e : _wordsMap)
	{
		priQue.push(e);
		if (priQue.size() > k)
		{
			priQue.pop();
		}
	}

	//赋值给_topWords
	while (!priQue.empty())
	{
		_topWords.push_back(priQue.top().first);
		priQue.pop();
	}

	std::sort(_topWords.begin(), _topWords.end());
}

}//end of namespace
